package org.streets.workflow.engine.persistence;

import java.util.List;

import org.streets.workflow.engine.IProcessDefinition;
import org.streets.workflow.engine.IProcessInstance;
import org.streets.workflow.engine.IProcessTrace;
import org.streets.workflow.engine.ITaskInstance;
import org.streets.workflow.engine.IToken;
import org.streets.workflow.engine.IWorkItem;
import org.streets.workflow.engine.entities.ProcessDefinition;
import org.streets.workflow.engine.entities.ProcessTrace;


/**
 * 数据存储接口，<br>
 *
 * 约定：以下划线开头的方法只提供给引擎本身使用，这些方法都经过特定优化。
 * 例如增加分区查询条件。
 *
 */
public interface IWorkflowDAO {
    /**
     * 插入或者更新ProcessInstance 。同时也会保存或更新流程变量<br/>
     * Save or update processinstance. 
     * If the processInstance.id is null then insert a new process instance record
     * and genarate a new id for it (save operation);
     * otherwise update the existent one.
     * 
     * @param process
     */
    public void saveOrUpdateProcess(IProcessInstance process);
    
    /**
     * 通过ID获得ProcessInstance对象。
     * “活的”是指ProcessInstance.state=INITIALIZED Or ProcessInstance.state=STARTED Or ProcessInstance=SUSPENDED的流程实例
     * @param processId processInstance.id
     * @return process instance
     */
    public IProcessInstance findProcess(String processId, boolean alive);


    /**
     * 查找并返回同一个业务流程的所有实例
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param definitionId The id of the process definition.
     * @return A list of processInstance
     */
    public List<IProcessInstance> findProcesses(String definitionId);
    

    /**
     * 查找并返回同一个指定版本业务流程的所有实例
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param definitionId The id of the process definition.
     * @return A list of processInstance
     */
    public List<IProcessInstance> findProcesses(String definitionId, Integer version);

    /**
     * 计算活动的子流程实例的数量
     * @param taskId 父TaskInstance的Id
     * @return
     */
    public Integer countAliveSubProcess(String taskId);


    /**
     * 终止流程实例。将流程实例、活动的TaskInstance、活动的WorkItem的状态设置为CANCELED；并删除所有的token
     * 
     * @param processInstanceId
     */
    public void abortProcess(IProcessInstance process);

    /**
     * 
     * Suspend the indicated state
     * 
     * @param process
     */
    public void suspendProcess(IProcessInstance process);

    /**
     * 
     * Restore one process from suspended state
     * 
     * @param process
     */
    public void restoreProcess(IProcessInstance process);
              
    /**
     * 插入或者更新TaskInstance。<br/>
     * Save or update task instance. If the taskInstance.id is null then insert a new task instance record
     * and generate a new id for it ;
     * otherwise update the existent one. 
     * @param taskInstance
     */
    public void saveOrUpdateTask(ITaskInstance task);

    /**
     * 终止TaskInstance。将任务实例及其所有的“活的”WorkItem变成Canceled状态。<br/>
     * "活的"WorkItem 是指状态等于INITIALIZED、STARTED或者SUSPENDED的WorkItem.
     * @param taskInstanceId
     */
    public void abortTask(ITaskInstance task);
    
    /**
     * 返回“活的”TaskInstance。<br/>
     * “活的”是指TaskInstance.state=INITIALIZED Or TaskInstance.state=STARTED 。
     * @param taskId
     * @return
     */
    public ITaskInstance findAliveTask(String taskId);

    /**
     * 获得activity的“活的”TaskInstance的数量<br/>
     * “活的”是指TaskInstance.state=INITIALIZED Or TaskInstance.state=STARTED 。
     * @param processId 流程实例ID
     * @param activityModelId 任务ID
     * @return
     */
    public Integer countAliveTaskForActivityModel(String processId, String activityModelId);

    /**
     * 返回某个Task已经结束的TaskInstance的数量。<br/>
     * “已经结束”是指TaskInstance.state=COMPLETED。
     * @param processId
     * @param taskModelId
     * @return
     */
    public Integer countCompletedTaskForTaskModel(String processId,String taskModelId);


    /**
     * Find the task instance by id
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param taskId
     * @return
     */
    public ITaskInstance findTask(String taskId);
    
    /**
     * 查询流程实例的所有的TaskInstance,如果activityId不为空，则返回该流程实例下指定环节的TaskInstance<br/>
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param processId  the id of the process instance
     * @param activityId  if the activityId is null, then return all the taskinstance of the processinstance;
     * @return
     */
    public List<ITaskInstance> findTasks(String processId, String activityId);


    /**
     * 查询出同一个stepNumber的所有TaskInstance实例
     * @param processId
     * @param step
     * @return
     */
    public List<ITaskInstance> findTasks(String processId, Integer step);
    
    
    /**
     * 调用数据库自身的机制所定TaskInstance实例。<br/>
     * 该方法主要用于工单的签收操作，在签收之前先锁定与之对应的TaskInstance。
     * @param taskId
     * @return
     */
    public void lockTask(String taskId);

    /**
     * 插入或者更新WorkItem<br/>
     * save or update workitem
     * @param workitem
     */
    public void saveOrUpdateWorkItem(IWorkItem workitem);

    /**
     * 返回任务实例的所有"活的"WorkItem的数量。<br>
     * "活的"WorkItem 是指状态等于INITIALIZED、STARTED或者SUSPENDED的WorkItem。
     * @param taskId
     * @return
     */
    public Integer countAliveWorkItem(String taskId);
    
    /**
     * Find workItem by id
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param itemId
     * @return
     */
    public IWorkItem findWorkItem(String itemId);
    
    /**
     * 
     * @param taskId
     * @return
     */
    public List<IWorkItem> findWorkItems(String taskId);

    /**
     * 根据操作员的Id返回其待办工单。如果actorId==null，则返回系统所有的待办任务<br/>
     * 待办工单是指状态等于INITIALIZED或STARTED工单<br/>
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param actorId
     * @return
     */
    public List<IWorkItem> findTodoWorkItems(String actorId);
    /**
     * 查找操作员在某个流程实例中的待办工单。
     * 如果processInstanceId为空，则等价于调用findTodoWorkItems(String actorId)
     * 待办工单是指状态等于INITIALIZED或STARTED工单<br/>
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param actorId
     * @param processId
     * @return
     */
    public List<IWorkItem> findTodoWorkItems(String actorId, String processId);
    
    /**
     * 查找操作员在某个流程某个任务上的待办工单。
     * actorId，processId，taskId都可以为空（null或者""）,为空的条件将被忽略
     * 待办工单是指状态等于INITIALIZED或STARTED工单<br/>
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param actorId
     * @param definitionId
     * @param taskModelId
     * @return
     */
    public List<IWorkItem> findTodoWorkItems(String actorId ,String definitionId, String taskModelId);

    /**
     * 查询任务实例的所有"已经结束"WorkItem。<br>
     * 
     * State 所以必须有关联条件WorkItem.state=IWorkItem.COMPLTED 
     * -1 反回全部
     * @param taskId 任务实例Id
     * @return
     */
    public List<IWorkItem> findCompletedWorkItems(String taskId);
    
    
    /**
     * 删除处于初始化状态的workitem。
     * 此方法用于签收Workitem时，删除其他Actor的WorkItem
     * @param taskId
     */
    public void deleteInitializedWorkItems(String taskId);

    
    /**
     * 根据操作员的Id返回其已办工单。如果actorId==null，则返回系统所有的已办任务
     * 已办工单是指状态等于COMPLETED或CANCELED的工单<br/>
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param actorId
     * @return
     */
    public List<IWorkItem> findHaveDoneWorkItems(String actorId);
    
    /**
     * 查找操作员在某个流程实例中的已办工单。
     * 如果processId为空，则等价于调用findHaveDoneWorkItems(String actorId)
     * 已办工单是指状态等于COMPLETED或CANCELED的工单<br/>
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param actorId
     * @param processId
     * @return
     */
    public List<IWorkItem> findHaveDoneWorkItems(String actorId, String processId);
    
    /**
     * 查找操作员在某个流程某个任务上的已办工单。
     * actorId，definitionId，taskModelId都可以为空（null或者""）,为空的条件将被忽略
     * 已办工单是指状态等于COMPLETED或CANCELED的工单<br/>
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param actorId
     * @param processId
     * @param taskId
     * @return
     */
    public List<IWorkItem> findHaveDoneWorkItems(String actorId, String definitionId, String taskModelId);
        
    /**
     * Save token
     * @param token
     */
    public void saveOrUpdateToken(IToken token);

    /**
     * 统计流程任意节点的活动Token的数量。对于Activity节点，该数量只能取值1或者0，大于1表明有流程实例出现异常。
     * @param processId
     * @param nodeId
     * @return
     */
    public Integer countAliveTokenForNode(String processId, String nodeId);


    /**
     * (Engine没有引用到该方法，提供给业务系统使用，20090303)
     * @param tokenId
     * @return
     */
    public IToken findToken(String tokenId);

    /**
     * Find all the tokens for process instance ,and the nodeId of the token must equals to the second argument.
     * @param processId the id of the process instance
     * @param nodeId if the nodeId is null ,then return all the tokens of the process instance.
     * @return
     */
    public List<IToken> findTokens(String processId, String nodeId);

    /**
     * 删除某个节点的所有token
     * @param processId
     * @param nodeId
     */
    public void deleteTokens(String processId,String nodeId);

    /**
     * 删除某些节点的所有token
     * @param processId
     * @param nodeIdsList
     */
    public void deleteTokens(String processId,List<String> nodeIdsList);

    /**
     * 删除token
     * @param token
     */
    public void deleteToken(IToken token);

    /**
     * Save or update the workflow definition. The version will be increased automatically when insert a new record.<br>
     * 保存流程定义，如果同一个ProcessId的流程定义已经存在，则版本号自动加1。
     * @param def
     */
    public void saveOrUpdateDefinition(ProcessDefinition def);
    
    /**
     * Find workflow definition by workflow process id and version<br>
     * 根据ProcessId和版本号返回流程定义
     * @param definitionId
     * @param version
     * @return
     */
    public IProcessDefinition findDefinition(String definitionId, int version);
                
    /**
     * Find all the workflow definitions for the workflow process id.<br>
     * 根据ProcessId 返回所有版本的流程定义
     * @param definitionId
     * @return
     */
    public List<ProcessDefinition> findDefinitions(String definitionId);

    /**
     * Find all of the latest version of workflow definitions.<br>
     * 返回系统中所有的最新版本的有效流程定义
     * @return
     */
    public List<IProcessDefinition> findAllDefinitions();
    
//    /**
//     * 返回最新版本号(忽略是否发布)
//     * @param processId
//     * @return
//     */
//    public Integer findTheLatestVersionNumberIgnoreState(String processId);
    
    
    public void saveOrUpdateProcessTrace(IProcessTrace trace);
    /**
     * 20090923 modified by wmj2003
     * 根据流程实例ID查找流程实例运行轨迹
     * @param processId 流程实例ID
     * @return
     */
    public List<ProcessTrace> findProcessTraces(String processId);
    
    
    /**
     * 获得操作员所要操作工单的总数量
     * publishUser如果为null，获取全部
     * @param actorId 操作员主键 
     * @param publishUser 流程定义发布者
     * @return
     * @author lifw555@gmail.com
     * @throws RuntimeException
     */
    public Integer countTodoWorkItems(String actorId,String publishUser) throws RuntimeException;

    /**
     * 获得操作员所要操作工单列表（分页）
     * publishUser如果为null，获取全部
     * @param actorId 操作员主键
     * @param publishUser 流程定义发布者
     * @param pageSize 每页显示的条数
     * @param pageNumber 当前页数
     * @return
     * @author lifw555@gmail.com
     * @throws RuntimeException
     */
	public List<IWorkItem> findTodoWorkItems(String actorId, String publishUser, int pageSize, int pageNumber) throws RuntimeException;

	/**
	 * 获得操作员完成的工单总数量
	 * publishUser如果为null，获取全部
	 * @param actorId 操作员主键 
	 * @param publishUser 流程定义发布者
	 * @return
	 * @author lifw555@gmail.com
	 * @throws RuntimeException
	 */
	public Integer countHaveDoneWorkItems(String actorId, String publishUser) throws RuntimeException;
	
	/**
	 * 获得操作员发起的工作流实例总数量
	 * publishUser如果为null，获取全部
	 * @param actorId 操作员主键
	 * @param publishUser 流程定义发布者
	 * @return
	 * @author lifw555@gmail.com
	 * @throws RuntimeException
	 */
	public Integer countProcessByCreator(String creatorId) throws RuntimeException;
	
	/**
	 * 获得操作员发起的工作流实例列表（分页）
	 * publishUser如果为null，获取全部
	 * @param actorId 操作员主键
	 * @param publishUser 流程定义发布者
	 * @param pageSize 每页显示的条数
	 * @param pageNumber 当前页数
	 * @return
	 * @author lifw555@gmail.com
	 * @throws RuntimeException
	 */
	public List<IProcessInstance> findProcessesByCreator(String creatorId,String publishUser,int pageSize,int pageNumber) throws RuntimeException; 

	/**
	 * 获得工作流发布者发起的所有流程定义的工作流实例总数量
	 * @param publishUser 工作流发布者
	 * @return
	 * @author lifw555@gmail.com
	 * @throws RuntimeException
	 */
	public Integer countProcessByPublisher(String publishUser) throws RuntimeException;
	
	/**
	 * 获得工作流发布者发起的所有流程定义的工作流实例列表（分页）
	 * @param publishUser 工作流发布者
	 * @param pageSize 每页显示的条数
	 * @param pageNumber 当前页数
	 * @return
	 * @author lifw555@gmail.com
	 * @throws RuntimeException
	 */
	public List<IProcessInstance> findProcessesByPublishUser(String publishUser, int pageSize, int pageNumber) throws RuntimeException;
	
}
